//useTable.ts
import {nextTick, ref} from 'vue'
import type {Ref} from 'vue'

/**
 * 表格配置接口
 * @interface TableConfig
 * @property {number} pageSize - 每页显示的数据条数，默认为10
 * @property {boolean} remote - 是否为远程加载数据，默认为true
 * @property {number} maxHeight - 表格最大高度，默认为300
 * @property {number} minHeight - 表格最小高度，默认为300
 * @property {boolean} bordered - 是否显示边框，默认为false
 * @property {boolean} singleLine - 是否单行显示，默认为false
 * @property {boolean} striped - 是否显示斑马纹，默认为true
 * @property {Function} api - 获取数据的接口方法，需要返回Promise
 * @property {boolean} immediate - 是否在初始化时立即加载数据，默认为true
 */
export interface TableConfig {
  pageSize?: number
  remote?: boolean
  maxHeight?: number
  minHeight?: number
  bordered?: boolean
  singleLine?: boolean
  striped?: boolean
  api?: (params: any) => Promise<any> // 请求接口方法
  immediate?: boolean // 是否立即请求数据
  rowKey: string
}

/**
 * 请求参数接口
 * @interface RequestParams
 * @property {number} size - 每页数据条数
 * @property {number} current - 当前页码
 * @property {any} [key: string] - 其他可能的查询参数
 */
export interface RequestParams {
  size: number
  current: number

  [key: string]: any
}

/**
 * 表格组合式函数
 * @template T - 表格数据类型
 * @param {TableConfig} config - 表格配置对象
 * @returns {Object} 返回表格相关的状态和方法
 */
export function useTable<T = any>(config: TableConfig = {}) {
  // 表格数据
  const dataRef = ref<T[]>([]) as Ref<T[]>

  // 加载状态
  const loading = ref(false)

  // 分页配置
  const pagination = ref({
    page: 1,
    pageCount: 1,
    pageSize: config.pageSize || 10,
    itemCount: 0,
    prefix({itemCount}: { itemCount: number }) {
      return `共 ${itemCount} 条` // 显示总条数
    },
    showSizePicker: true, // 是否显示页面大小选择
    pageSizes: [10, 20, 30, 40], // 页面大小的选择项
    onUpdatePageSize: (pageSize: number) => handlePageSizeChange(pageSize) // 页大小变化时的回调
  })

  // 查询参数
  const searchParams = ref<RequestParams>({
    size: pagination.value.pageSize,
    current: pagination.value.page
  })

  // 表格基础配置
  const tableConfig = {
    bordered: config.bordered ?? false, // 是否显示表格边框
    singleLine: config.singleLine ?? false, // 是否单行显示
    maxHeight: config.maxHeight ?? 'calc(100vh - 300px)', // 最大高度
    minHeight: config.minHeight ?? '300px', // 最小高度
    remote: config.remote ?? true, // 是否为远程加载数据
    striped: config.striped ?? true, // 是否显示斑马纹
    style: {
      height: '100%',
      display: 'flex',
      flexDirection: 'column'
    }
  }

  /**
   * 获取表格数据
   */
  const loadData = async () => {
    if (!config.api) return // 如果没有传入 api，直接返回

    loading.value = true // 开始加载数据
    try {
      const res = await config.api({
        size: pagination.value.pageSize,
        current: pagination.value.page,
        ...searchParams.value // 合并查询参数
      })
      if (res) {
        // 更新数据和分页信息
        dataRef.value = res.records || []
        pagination.value.itemCount = res.total
        pagination.value.pageCount = res.pages

        // 如果当前页超出总页数，自动调整到最后一页
        if (pagination.value.page > pagination.value.pageCount) {
          handlePageChange(pagination.value.pageCount)
        }
      }
    } catch (error) {
      console.error('加载表格数据失败:', error) // 错误处理
    } finally {
      loading.value = false // 加载完毕
    }
  }

  /**
   * 排序回调
   * @param sorter 排序信息
   */
  const handleSorterChange = (sorter: any) => {
    searchParams.value = {
      ...searchParams.value,
      sortField: sorter?.columnKey,
      sortOrder: sorter?.order
    }
    loadData() // 排序变化后加载数据
  }

  /**
   * 过滤回调
   * @param filters 过滤信息
   */
  const handleFiltersChange = (filters: any) => {
    searchParams.value = {...searchParams.value, ...filters}
    loadData() // 过滤条件变化后加载数据
  }

  /**
   * 分页回调
   * @param page 当前页
   */
  const handlePageChange = (page: number) => {
    if (page !== pagination.value.page) {
      pagination.value.page = page // 更新当前页
      searchParams.value.current = page // 更新查询参数
      loadData() // 页码变化后加载数据
    }
  }

  /**
   * 页大小变化回调
   * @param pageSize 每页条数
   */
  const handlePageSizeChange = (pageSize: number) => {
    if (pageSize !== pagination.value.pageSize) {
      pagination.value.pageSize = pageSize // 更新每页条数
      searchParams.value.size = pageSize // 更新查询参数

      // 根据新的页大小调整页码
      const newPage = Math.ceil((pagination.value.page * pagination.value.pageSize) / pageSize)
      pagination.value.page = newPage
      searchParams.value.current = newPage

      loadData() // 页大小变化后加载数据
    }
  }

  /**
   * 刷新表格数据
   */
  const refresh = () => loadData() // 重新加载数据

  /**
   * 重置表格
   */
  const reset = () => {
    pagination.value.page = 1 // 重置为第一页
    searchParams.value = {size: pagination.value.pageSize, current: 1} // 重置查询参数
    loadData() // 重置后加载数据
  }

  // 如果配置了立即加载，则执行加载数据
  if (config.immediate !== false && config.api) {
    loadData() // 初始化时加载数据
  }
  const rowKey = config.rowKey;

  return {
    dataRef,
    loading,
    pagination,
    tableConfig,
    searchParams,
    handleSorterChange,
    handleFiltersChange,
    handlePageChange,
    handlePageSizeChange,
    refresh,
    reset,
    loadData,
    rowKey
  }
}
